<?php

namespace Biz\service;

use Biz\model\trade\Order as mOrder;
use Biz\model\trade\OrderPay;
use Biz\model\TradeMsg as mTradeMsg;
use Biz\model\TradeMsgTemplate as mTradeMsgTemplate;
use Biz\pockets\serviceTrait\_Async;
use Biz\tools\BizUrl;
use Doraemon\cache\MsgCounter;
use Doraemon\cache\MsgLastMsg;
use Doraemon\cache\PushQueue;
use Doraemon\tools\Log;
use Doraemon\tools\MiniProgramConfig;
use Doraemon\tools\MiniProgramNotice as tMiniProgramNotice;
/**
 * @deprecated
 */
class TradeMsg
{
    use _Async;

    const MSG_LIMIT = 30;
    const CUSTOM_MSG_CODE = 0;

    const MSG_CODE_101 = 101;//订单已发货
    const MSG_CODE_102 = 102;//订单已发货（有退款）
    const MSG_CODE_103 = 103;//支付完成
    const MSG_CODE_201 = 201;//商家同意退款（仅退款）
    const MSG_CODE_202 = 202;//商家拒绝退款（仅退款）
    const MSG_CODE_301 = 301;//商家同意退款（退货退款）
    const MSG_CODE_302 = 302;//商家拒绝退款（退货退款）
    const MSG_CODE_303 = 303;//商家确认收货并退款（退货退款）
    const MSG_CODE_401 = 401;//介入维权
    const MSG_CODE_402 = 402;//判定维权
    const MSG_CODE_501 = 501;//拼团失败自动退款
    const MSG_CODE_502 = 502;//拼团成功


    public static function sendMiniProgramGroupSuccessNotice($orderNo, $noticeData)
    {
        $parentNo = mOrder::getOrderParentNo($orderNo);
        $payInfos = OrderPay::getOrderPay("*",
            [
                'payWay' => OrderPay::_PAY_WAYS_MINIPROGRAM,
                'orderNo' => $orderNo,
                'orderPno' => $parentNo,
                'status' => OrderPay::STATUS_PAIED
            ]);
        if ($payInfos) {
            foreach ($payInfos as $payInfo) {
                $payOrderInfo = json_decode($payInfo['pay_order_info'], true);
                parse_str($payOrderInfo['package'], $params);
                tMiniProgramNotice::sendNotice(MiniProgramConfig::APP_NAME_BIZ, $payOrderInfo['open_id'], tMiniProgramNotice::MSG_TEMPLATE_ORDER_GROUP_SUCC,
                    $params['prepay_id'], $orderNo, $noticeData);
            }
        }
    }

    public static function sendMiniProgramGroupFailNotice($orderNo, $noticeData)
    {
        $parentNo = mOrder::getOrderParentNo($orderNo);
        $payInfos = OrderPay::getOrderPay("*",
            [
                'payWay' => OrderPay::_PAY_WAYS_MINIPROGRAM,
                'orderNo' => $orderNo,
                'orderPno' => $parentNo,
                'status' => OrderPay::STATUS_PAIED
            ]);
        if ($payInfos) {
            foreach ($payInfos as $payInfo) {
                $payOrderInfo = json_decode($payInfo['pay_order_info'], true);
                parse_str($payOrderInfo['package'], $params);
                tMiniProgramNotice::sendNotice(MiniProgramConfig::APP_NAME_BIZ, $payOrderInfo['open_id'], tMiniProgramNotice::MSG_TEMPLATE_ORDER_GROUP_FAIL,
                    $params['prepay_id'], $orderNo, $noticeData);
            }
        }
    }

    public static function sendMiniProgramShipNotice($orderNo, $noticeData)
    {
        $parentNo = mOrder::getOrderParentNo($orderNo);
        $payInfos = OrderPay::getOrderPay("*",
            [
                'payWay' => OrderPay::_PAY_WAYS_MINIPROGRAM,
                'orderNo' => $orderNo,
                'orderPno' => $parentNo,
                'status' => OrderPay::STATUS_PAIED
            ]);
        if ($payInfos) {
            foreach ($payInfos as $payInfo) {
                $payOrderInfo = json_decode($payInfo['pay_order_info'], true);
                parse_str($payOrderInfo['package'], $params);
                tMiniProgramNotice::sendNotice(MiniProgramConfig::APP_NAME_BIZ, $payOrderInfo['open_id'], tMiniProgramNotice::MSG_TEMPLATE_ORDER_SHIP,
                    $params['prepay_id'], $orderNo, $noticeData);
            }
        }
    }

    public static function sendJieXuanProgramShipNotice($orderNo, $noticeData)
    {
        try {
            $parentNo = mOrder::getOrderParentNo($orderNo);
            $payInfos = OrderPay::getOrderPay("*",
                [
                    'orderNo' => $orderNo,
                    'orderPno' => $parentNo,
                    'status' => OrderPay::STATUS_PAIED
                ]);
            if ($payInfos) {
                foreach ($payInfos as $payInfo) {
                    $payOrderInfo = json_decode($payInfo['pay_order_info'], true);
                    parse_str($payOrderInfo['package'], $params);
                    tMiniProgramNotice::sendNotice(MiniProgramConfig::APP_NAME_THE_PARAGRAPH, $payOrderInfo['open_id'], tMiniProgramNotice::MSG_TEMPLATE_THE_PARAGRAPH_ORDER_SHIP,
                        $params['prepay_id'], $orderNo, $noticeData);
                }
            }
        } catch (\Exception $e) {
            Log::info('节选小程序发货通知', [
                'order_no' => $orderNo,
                'noticedata' => $noticeData
            ]);
        }

    }

    public static function sendJieXuanProgramPayNotice($orderNo, $noticeData)
    {
        try {
            $parentNo = mOrder::getOrderParentNo($orderNo);
            $payInfos = OrderPay::getOrderPay("*",
                [
                    'orderNo' => $orderNo,
                    'orderPno' => $parentNo,
                    'status' => OrderPay::STATUS_PAIED
                ]);
            if ($payInfos) {
                foreach ($payInfos as $payInfo) {
                    $payOrderInfo = json_decode($payInfo['pay_order_info'], true);
                    parse_str($payOrderInfo['package'], $params);
                    tMiniProgramNotice::sendNotice(MiniProgramConfig::APP_NAME_THE_PARAGRAPH, $payOrderInfo['open_id'], tMiniProgramNotice::MSG_TEMPLATE_THE_PARAGRAPH_NEW_ORDER,
                        $params['prepay_id'], $orderNo, $noticeData);
                }
            }
        } catch (\Exception $e) {
            Log::info('节选小程序发货通知', [
                'order_no' => $orderNo,
                'noticedata' => $noticeData
            ]);
        }
    }


    public static function getMsgList($uid, $start_id = 0, $limit = self::MSG_LIMIT)
    {
        $msgList = mTradeMsg::getMsgList($uid, $start_id, $limit);
        return $msgList;
    }

    public static function addMsg($msgCode, $uid, $msgParams = [])
    {
        $msgData = self::assembledMsg($msgCode, $uid, $msgParams);
        mTradeMsg::insert($msgData);
        self::_async($msgData);
    }

    public static function _async_addMsg($msgData)
    {
        //更新最后一条系统消息
        $content = '【' . $msgData['title'] . '】' . $msgData['detail'];
        MsgLastMsg::setLastMsg($msgData["to_uid"], MsgLastMsg::TYPE_TRADE_MSG, json_encode([
            'addtime' => time(),
            'message' => $content
        ]));
        // 更新系统消息计数器
        MsgCounter::addMsgNum($msgData["to_uid"], MsgCounter::TYPE_TRADEMSG);
        //增加app图标计数
        PushQueue::insertQueue("NoticeBadge/setBadge", [
            'uid' => $msgData["to_uid"],
            'total' => MsgCounter::getSumMsgNum($msgData["to_uid"])
        ], PushQueue::QUEUE_NOTICE_BADGE);
        return true;
    }

    private static function assembledMsg($msgCode, $uid, $msgParams)
    {
        $msgTemplate = mTradeMsgTemplate::get("*", [
            "AND" => [
                "msg_code" => $msgCode,
                "status" => mTradeMsgTemplate::STATUS_NORMAL
            ]
        ]);
        if ($msgTemplate) {
            $msgData = [];
            $msgData["to_uid"] = $uid;
            if ($msgTemplate['params']) {
                $msgResData = [];
                $needParams = explode(",", $msgTemplate['params']);
                foreach ($needParams as $needParam) {
                    if (!isset($msgParams[$needParam])) {
                        throw new \Exception("缺失参数：{$needParam},无法发送该类型系统消息");
                    } else {
                        $msgResData[$needParam] = self::getSrcData($msgParams[$needParam], $needParam);
                    }
                }
                $msgTemplate = self::replaceMsgData($msgTemplate, $msgResData, $msgParams);
            }
            $msgData["title"] = isset($msgParams["title"]) ? $msgParams["title"] : $msgTemplate["title"];
            $msgData["img"] = isset($msgParams["img"]) ? $msgParams["img"] : $msgTemplate["img"];
            $msgData["link"] = isset($msgParams["link"]) ? $msgParams["link"] : $msgTemplate["link"];
            $msgData["detail"] = isset($msgParams["detail"]) ? $msgParams["detail"] : $msgTemplate["detail"];
            $msgData["remark"] = isset($msgParams["remark"]) ? $msgParams["remark"] : $msgTemplate["remark"];
            $msgData["msg_code"] = $msgCode;
            $msgData["send_time"] = date("Y-m-d H:i:s");
            $msgData["status"] = mTradeMsg::STATUS_NORMAL;
        } else {
            throw new \Exception("系统消息类型错误");
        }
        return $msgData;
    }

    private static function replaceMsgData($msgTemplate, $msgResData, $msgParams)
    {
        foreach ($msgTemplate as &$msgText) {
            $msgText = preg_replace_callback('/{([^{}]+)}/', function ($matches) use ($msgResData, $msgParams) {
                if ($matches[1]) {
                    $replaceKey = explode("#", $matches[1]);
                    if (count($replaceKey) > 1) {
                        return $msgResData[$replaceKey[0]][$replaceKey[1]];
                    } else {
                        return $msgParams[$replaceKey[0]];
                    }
                } else {
                    return $matches[0];
                }
            }, $msgText);
        }
        return $msgTemplate;
    }

    private static function getSrcData($resId, $resType)
    {
        $res = [];
        switch ($resType) {
            case "refund_order_no":
                $res = ['h5' => BizUrl::h5OrderRefundInfo($resId)];
                break;
        }
        return $res;
    }
}